From 52f6acd398b7a83f53f3605a9d50d51c3b48286c Mon Sep 17 00:00:00 2001 From: Arjan Molenaar Date: Sat, 21 Jan 2023 14:54:12 +0100 Subject: [PATCH] macos: Send dragging events directly to the display Instead of adding events to the application event queue, dispatch them directly to the right display. We know this when the event is to be dispatched. This is the same as used for the `sendEvent` method in `GdkMacosWindow`. To achieve this I factored out the generic NSEvent to GdkEvent translation. We can send an event directly, when we receive it in the GdkMacosWindow directly from the OS. --- gdk/macos/GdkMacosWindow.c | 16 +-- gdk/macos/gdkmacosdisplay-private.h | 2 +- gdk/macos/gdkmacosdisplay-translate.c | 155 +++++++++++++----------- gdk/macos/gdkmacoseventsource-private.h | 1 - gdk/macos/gdkmacoseventsource.c | 2 +- 5 files changed, 95 insertions(+), 81 deletions(-) diff --git a/gdk/macos/GdkMacosWindow.c b/gdk/macos/GdkMacosWindow.c index 79a25c04d3..0636018c93 100644 --- a/gdk/macos/GdkMacosWindow.c +++ b/gdk/macos/GdkMacosWindow.c @@ -146,7 +146,7 @@ typedef NSString *CALayerContentsGravity; * * TODO: Can we improve grab breaking to fix this? */ - _gdk_macos_display_send_button_event ([self gdkDisplay], event); + _gdk_macos_display_send_event ([self gdkDisplay], event); _gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time); @@ -698,23 +698,23 @@ typedef NSString *CALayerContentsGravity; - (void)draggingSession:(NSDraggingSession *)session movedToPoint:(NSPoint)screenPoint { NSInteger sequence_number = [session draggingSequenceNumber]; - GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface)); + GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (gdk_surface))); GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number); int x, y; - _gdk_macos_event_source_queue_event ([NSApp currentEvent]); + _gdk_macos_display_send_event (display, [NSApp currentEvent]); - _gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display), screenPoint.x, screenPoint.y, &x, &y); + _gdk_macos_display_from_display_coords (display, screenPoint.x, screenPoint.y, &x, &y); _gdk_macos_drag_surface_move (GDK_MACOS_DRAG (drag), x, y); } - (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation { NSInteger sequence_number = [session draggingSequenceNumber]; - GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface)); - GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number); + GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (gdk_surface))); + GdkDrag *drag = _gdk_macos_display_find_drag (display, sequence_number); - _gdk_macos_event_source_queue_event ([NSApp currentEvent]); + _gdk_macos_display_send_event (display, [NSApp currentEvent]); gdk_drag_set_selected_action (drag, _gdk_macos_drag_ns_operation_to_action (operation)); if (gdk_drag_get_selected_action (drag) != 0) @@ -722,7 +722,7 @@ typedef NSString *CALayerContentsGravity; else gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET); - _gdk_macos_display_set_drag (GDK_MACOS_DISPLAY (display), [session draggingSequenceNumber], NULL); + _gdk_macos_display_set_drag (display, [session draggingSequenceNumber], NULL); } // end diff --git a/gdk/macos/gdkmacosdisplay-private.h b/gdk/macos/gdkmacosdisplay-private.h index 122d004cec..9fc910ec2e 100644 --- a/gdk/macos/gdkmacosdisplay-private.h +++ b/gdk/macos/gdkmacosdisplay-private.h @@ -155,7 +155,7 @@ void _gdk_macos_display_surface_became_key (GdkMacosDisp GdkMacosSurface *surface); void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self); const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self); -void _gdk_macos_display_send_button_event (GdkMacosDisplay *self, +void _gdk_macos_display_send_event (GdkMacosDisplay *self, NSEvent *nsevent); void _gdk_macos_display_warp_pointer (GdkMacosDisplay *self, int x, diff --git a/gdk/macos/gdkmacosdisplay-translate.c b/gdk/macos/gdkmacosdisplay-translate.c index b06dc83dbe..f6d4a23991 100644 --- a/gdk/macos/gdkmacosdisplay-translate.c +++ b/gdk/macos/gdkmacosdisplay-translate.c @@ -723,6 +723,85 @@ fill_scroll_event (GdkMacosDisplay *self, return g_steal_pointer (&ret); } + +static GdkEvent * +fill_event (GdkMacosDisplay *self, + GdkMacosWindow *window, + NSEvent *nsevent, + int x, + int y) +{ + GdkMacosSurface *surface = [window gdkSurface]; + NSEventType event_type = [nsevent type]; + GdkEvent *ret = NULL; + + switch ((int)event_type) + { + case NSEventTypeLeftMouseDown: + case NSEventTypeRightMouseDown: + case NSEventTypeOtherMouseDown: + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseUp: + ret = fill_button_event (self, surface, nsevent, x, y); + break; + + case NSEventTypeLeftMouseDragged: + case NSEventTypeRightMouseDragged: + case NSEventTypeOtherMouseDragged: + case NSEventTypeMouseMoved: + ret = fill_motion_event (self, surface, nsevent, x, y); + break; + + case NSEventTypeMagnify: + case NSEventTypeRotate: + ret = fill_pinch_event (self, surface, nsevent, x, y); + break; + + case NSEventTypeMouseExited: + case NSEventTypeMouseEntered: + { + GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self)); + GdkDevice *pointer = gdk_seat_get_pointer (seat); + GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer); + + if ([(GdkMacosWindow *)window isInManualResizeOrMove]) + { + ret = GDK_MACOS_EVENT_DROP; + } + else if (grab == NULL) + { + if (event_type == NSEventTypeMouseExited) + [[NSCursor arrowCursor] set]; + + ret = synthesize_crossing_event (self, surface, nsevent, x, y); + } + } + + break; + + case NSEventTypeKeyDown: + case NSEventTypeKeyUp: + case NSEventTypeFlagsChanged: { + GdkEventType type = _gdk_macos_keymap_get_event_type (nsevent); + + if (type) + ret = fill_key_event (self, surface, nsevent, type); + + break; + } + + case NSEventTypeScrollWheel: + ret = fill_scroll_event (self, surface, nsevent, x, y); + break; + + default: + break; + } + + return ret; +} + static gboolean is_mouse_button_press_event (NSEventType type) { @@ -1083,7 +1162,6 @@ _gdk_macos_display_translate (GdkMacosDisplay *self, GdkMacosWindow *window; NSEventType event_type; NSWindow *event_window; - GdkEvent *ret = NULL; int x; int y; @@ -1191,79 +1269,15 @@ _gdk_macos_display_translate (GdkMacosDisplay *self, _gdk_macos_display_clear_sorting (self); } } - - switch ((int)event_type) - { - case NSEventTypeLeftMouseDown: - case NSEventTypeRightMouseDown: - case NSEventTypeOtherMouseDown: - case NSEventTypeLeftMouseUp: - case NSEventTypeRightMouseUp: - case NSEventTypeOtherMouseUp: - ret = fill_button_event (self, surface, nsevent, x, y); - break; - - case NSEventTypeLeftMouseDragged: - case NSEventTypeRightMouseDragged: - case NSEventTypeOtherMouseDragged: - case NSEventTypeMouseMoved: - ret = fill_motion_event (self, surface, nsevent, x, y); - break; - - case NSEventTypeMagnify: - case NSEventTypeRotate: - ret = fill_pinch_event (self, surface, nsevent, x, y); - break; - - case NSEventTypeMouseExited: - case NSEventTypeMouseEntered: - { - GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self)); - GdkDevice *pointer = gdk_seat_get_pointer (seat); - GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer); - - if ([(GdkMacosWindow *)window isInManualResizeOrMove]) - { - ret = GDK_MACOS_EVENT_DROP; - } - else if (grab == NULL) - { - if (event_type == NSEventTypeMouseExited) - [[NSCursor arrowCursor] set]; - - ret = synthesize_crossing_event (self, surface, nsevent, x, y); - } - } - - break; - - case NSEventTypeKeyDown: - case NSEventTypeKeyUp: - case NSEventTypeFlagsChanged: { - GdkEventType type = _gdk_macos_keymap_get_event_type (nsevent); - - if (type) - ret = fill_key_event (self, surface, nsevent, type); - - break; - } - - case NSEventTypeScrollWheel: - ret = fill_scroll_event (self, surface, nsevent, x, y); - break; - - default: - break; - } - - return ret; + return fill_event (self, window, nsevent, x, y); } void -_gdk_macos_display_send_button_event (GdkMacosDisplay *self, - NSEvent *nsevent) +_gdk_macos_display_send_event (GdkMacosDisplay *self, + NSEvent *nsevent) { GdkMacosSurface *surface; + GdkMacosWindow *window; GdkEvent *event; int x; int y; @@ -1272,7 +1286,8 @@ _gdk_macos_display_send_button_event (GdkMacosDisplay *self, g_return_if_fail (nsevent != NULL); if ((surface = find_surface_for_ns_event (self, nsevent, &x, &y)) && - (event = fill_button_event (self, surface, nsevent, x, y))) + (window = (GdkMacosWindow *)_gdk_macos_surface_get_native (surface)) && + (event = fill_event (self, window, nsevent, x, y))) _gdk_windowing_got_event (GDK_DISPLAY (self), _gdk_event_queue_append (GDK_DISPLAY (self), event), event, diff --git a/gdk/macos/gdkmacoseventsource-private.h b/gdk/macos/gdkmacoseventsource-private.h index 66579546d2..09853a18ac 100644 --- a/gdk/macos/gdkmacoseventsource-private.h +++ b/gdk/macos/gdkmacoseventsource-private.h @@ -34,7 +34,6 @@ typedef enum GSource *_gdk_macos_event_source_new (GdkMacosDisplay *display); NSEvent *_gdk_macos_event_source_get_pending (void); gboolean _gdk_macos_event_source_check_pending (void); -void _gdk_macos_event_source_queue_event (NSEvent *event); G_END_DECLS diff --git a/gdk/macos/gdkmacoseventsource.c b/gdk/macos/gdkmacoseventsource.c index 6c4a962ae0..121efc679b 100644 --- a/gdk/macos/gdkmacoseventsource.c +++ b/gdk/macos/gdkmacoseventsource.c @@ -653,7 +653,7 @@ _gdk_macos_event_source_get_pending (void) return event; } -void +static void _gdk_macos_event_source_queue_event (NSEvent *event) { /* Just used to wake us up; if an event and a FD arrived at the same -- 2.30.2